"""
爬虫A站视频
https://www.acfun.cn/
代码实现步骤
1. 发送请求：对于视频播放页面url地址发送请求
2. 获取数据：获取服务器返回response响应数据
3. 解析数据：提取我们想要的数据内容 视频标题 以及 m3u8 链接
4. 发送请求：对于 m3u8 链接 发送请求
5. 获取数据：获取服务器返回response响应数据（获取总共 ts 片段内容）
6. 解析数据：提取所有 ts 文件 url（视频片段url地址）
7. 保存数据：把所有的视频保存下来，然后合成一个整体视频内容
"""

import requests  # 数据请求模块 pip install requests  在cmd里面 输入命令
import re  # 导入正则表达式模块 内置模块，不需要安装
import json  # 字符串转json
import pprint  # 格式化输出模块

# 请求头 用了伪装python代码，为了被服务器识别出来 是爬虫程序 一种简单反爬虫手段
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'
}
# 页面数据地址
list_url = "https://www.acfun.cn/v/list86/index.htm"


# 获取多页数据
def getMorePageData():
    for page in range(1, 17):
        data = {
            'sortField': 'rankScore',
            'duration': 'all',
            'date': 'default',
            'page': page,
            'quickViewId': 'listwrapper',
            'reqID': page,
            'ajaxpipe': '1',
            't': 1659250097080
        }
        getVideoList(param=data)


# 获取一页数据
def getVideoList(param):
    response_list = requests.get(url=list_url, params=param, headers=headers)
    # print(response_list.text)
    id_list = re.findall('<a href=\'(.*?)\'', response_list.text)
    for index in id_list:
        # print(index)
        getSignVideo(index)


# /v/ac35869529
def getSignVideo(id):
    """
    1. 发送请求：对于视频播放页面url地址发送请求
        用 python 代码去模拟浏览器对于 url地址发送请求
    """
    url = f'https://www.acfun.cn{id}'  # 确定请求 url 地址

    # 通过requests模块里面get请求方式，对应url地址发送请求，并且携带上 headers请求头伪装，最后用response自定义变量接收返回数据
    response = requests.get(url=url, headers=headers)

    # 2. 获取数据：获取服务器返回response响应数据
    # print(response.text)

    # 3 解析数据: 通过re模块里面findall的方法 在response.text 里面去找寻 标题数据
    title = re.findall('<title >(.*?) - AcFun弹幕视频网 - 认真你就输啦 \(\?\ω\?\)ノ- \( ゜- ゜\)つロ</title>', response.text)[0]
    video_info = re.findall('window.pageInfo = window.videoInfo = (.*?);', response.text)[0]
    # print(title)
    # print(video_info)
    try:
        json_data = json.loads(video_info)
    except Exception as result:
        print("保存视频出错：", title)
    else:
        # print(json_data)
        # pprint.pprint(json_data)

        # 字典取值
        m3u8_url = \
            json.loads(json_data['currentVideoInfo']['ksPlayJson'])['adaptationSet'][0]['representation'][0][
                'backupUrl'][0]
        # print(m3u8_url)
        # 4. 发送请求：对于 m3u8_url 链接 发送请求，并且携带上headers请求头伪装，获取响应体文本数据，用m3u8_data 自定义变量接收
        m3u8_data = requests.get(url=m3u8_url, headers=headers).text
        m3u8_data = re.sub('#E.*', '', m3u8_data).split()  # 把匹配出来的内容替换为空,并且将得到的值分割
        # print(m3u8_data)
        for ts in m3u8_data:
            ts_url = 'https://tx-safety-video.acfun.cn/mediacloud/acfun/acfun_video/' + ts
            ts_content = requests.get(url=url, headers=headers).content
            # 保存视频并合并，主要在于 mode='ab'，a 追加保存，b二进制数据 ab 以二进制数据追加保存
            with open('video\\' + title + '.mp4', mode='ab') as f:
                f.write(ts_content)
            # print(ts_url)
        print('视频保存完成：', title)


if __name__ == '__main__':
    # getVideoList()
    getMorePageData()